// A
/* #include<iostream>
#include<cstring>
#include<string>
#define INF 0x3f3f3f3f
#define N 50005
using namespace std;
int Next[N];
char str1[N],str2[N];
void getNext(char p[]){
    Next[0]=-1;
    int LEN=strlen(p);
    int j=0;
    int k=-1;

    while(j<LEN){
        if(k==-1||p[j]==p[k]) {
            k++;
            j++;
            Next[j]=k;
        }else{
            k=Next[k];
        }
    }
}
int KMP(char t[],char p[]){
    int tLen=strlen(t);
    int pLen=strlen(p);

    int i=0;
    int j=0;

    while(i<tLen&&j<pLen){
        if(j==-1||t[i]==p[j]){
            i++;
            j++;
            if(j==pLen&&i!=tLen){//当模式串到达结尾时，回到指定位置
                j=Next[j];
            }
        }
        else{
           j=Next[j];
        }
    }

    return j;//返回前缀的位置
}


int main(){
    while(scanf("%s",str1)!=EOF){
        scanf("%s",str2);
        getNext(str1);
        int res=KMP(str2,str1);
        if(res!=0){
            str1[res]='\0';//截取前缀
            printf("%s %d\n",str1,res);
        }
        else
            printf("0\n");
    }
    return 0;
} */
// B

/* #include<cstring>
#include<iostream>
#define N 2000007
using namespace std;
char sl[N],ss[N];
int nxt[N],LEN,len,cnt;
void getnext()
{
        int i=0;
        int j=-1;
        nxt[i]=j;
        while(i<len)
        {
                if(sl[i]==sl[j]||j==-1)
                {
                i++;
                j++;
                nxt[i]=j;
                }
                else
                j=nxt[j];
        }
}
void kmp()
{
        getnext();
        int i=0;
        int j=0;
        while(i<LEN)
        {
                if(sl[j]==ss[i]||j==-1)
                {
                        i++;
                        j++;
                        if(j==len)
                        {
                        cnt++;
                        }
                }
                else
                j=nxt[j];
        }
}
int main()
{
        int m;
        cin>>m;
        while(m--)
        {
                scanf("%s%s",sl,ss);
                len=strlen(sl);
                LEN=strlen(ss);
                cnt=0;
                kmp();
                cout<<cnt<<endl;
        }
return 0;
} */
// C
/* #include<cstdio>
#include<algorithm>
#include<iostream>
#include<map>
using namespace std;
int T,n,m,k,x,y,c,q,cnt;
map<int,int> row,col;
map<pair<int,int>,int> mp;
int main()
{
    cin>>T;
    cnt = 1;
    while(T--)
    {
        cin>>n>>m>>k;
        row.clear(),col.clear(),mp.clear();
        while(k--)
        {
            cin>>x>>y>>c;
            row[x] = x,col[y] = y;
            mp[pair<int,int> (x,y)] = c;
        }
        printf("Case #%d:\n",cnt++);
        cin>>q;
        while(q--)
        {
            cin>>c>>x>>y;
            if(c == 1) swap(row[x],row[y]);
            else if(c == 2) swap(col[x],col[y]);
            else
                printf("%d\n",mp[pair<int,int> (row[x],col[y])]);
        }
    }
    return 0;
} */

// D

/* #include<algorithm>
#include<cstring>
#include<iostream>
#include<map>
using namespace std;
#define MAX 16000007
char str[MAX];
char p;
map<string,int> mp;//建立map映射
int main()
{
    int n,nc,t,LEN,ans,first=0;

    cin>>t;

    while(t--)
    {
        if(first)//判断是否是第一个输入
            cout<<endl;
        cin>>n>>nc;
        scanf("%s",str);
        LEN=strlen(str);
        ans=0;
        mp.clear();
        for(int i=n;i<=LEN;i++)
        {
            string s1(str+i-n,n);//取出字符串

            if(!mp[s1])
                ans++,mp[s1]=1;
        }
        cout<<ans;
        first=1;
    }
    return 0;
} */

// E
#include <algorithm>
#include <cstring>
#include <iostream>
#include <map>
#include <string>
#define lowbit(x) (x & (-x))
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int maxN = 1e5 + 7;
const ull Hash = 1e9 + 7;
char s1[maxN], s2[maxN];
int len1, len2;
ull hash_1[maxN], hash_2[maxN], pre_hash[maxN], cnt, num_hash[maxN];
bool cmp(ull e1, ull e2) {
    return e1 < e2;
}
void pre_did() {
    memset(num_hash, 0, sizeof(num_hash));
    hash_1[0] = 0;
    hash_2[0] = 0;
    len1 = (int)strlen(s1 + 1);
    len2 = (int)strlen(s2 + 1);
    for (int i = 1; i <= len1; i++) { hash_1[i] = hash_1[i - 1] * Hash + s1[i]; }
    for (int i = 1; i <= len2; i++) { hash_2[i] = hash_2[i - 1] * Hash + s2[i]; }
}
int main() {
    pre_hash[0] = 1;
    for (int i = 1; i < maxN; i++) pre_hash[i] = pre_hash[i - 1] * Hash;
    while (scanf("%s", s1 + 1) != EOF) {
        getchar();
        scanf("%s", s2 + 1);
        pre_did();
        int len = 0, r = min(len1, len2), mid = 0, ans = 0;
        while (len <= r) {
            mid = (len + r) >> 1;
            cnt = 0;
            for (int i = mid; i <= len1; i++) {
                num_hash[++cnt] =
                    (hash_1[i] -
                     hash_1[i - mid] * pre_hash[mid]);  //剪去前面一部分，留下长度为mid的量
            }
            bool flag = false;
            sort(num_hash + 1, num_hash + 1 + cnt, cmp);
            for (int i = mid; i <= len2; i++) {
                ull x = (hash_2[i] - hash_2[i - mid] * pre_hash[mid]);
                if (*lower_bound(num_hash + 1, num_hash + 1 + cnt, x) ==
                    x)  //若存存在这样的长度，说明目前长度并非最长值
                {
                    flag = true;
                    break;
                }
            }
            if (flag) {
                len = mid + 1;
                ans = mid;
            } else {
                r = mid - 1;
            }
        }
        printf("%d\n", ans);
        getchar();
    }
    return 0;
}